package com.yangyouli.unity_demo_server.util;

import java.io.UnsupportedEncodingException;

import org.apache.log4j.Logger;

import com.yangyouli.unity_demo_server.server.Request;

/**
 * 处理数据
 * @author 24279
 *
 */
public class Message {
	// 读取到的数据
	private byte[] data = new byte[1024];
	// data 数组中存储的数据个数
	private int dataCount = 0;
	static Logger log = Logger.getLogger(Message.class);
	
	/**
	 * 将传来的数据打包成 byte 数组
	 * @param requestClassName
	 * @param data
	 * @return
	 * 前4个字节为 int，标识正式数据长度
	 * 然后为 reqyestClassName 的 byte 数组
	 * 然后为英文的冒号 :，分割数据
	 * 最后为 data 的 byte 数组
	 */
	public static byte[] packageData (String requestClassName, String data) {
		// 其中的一个参数为空则返回 null
		if (requestClassName == null || requestClassName.isEmpty() || data == null || data.isEmpty()) return null;
		byte[] colonBytes = null;
		byte[] requestClassNameBytes = null;
		byte[] dataBytes = null;
		try {
			colonBytes = ":".getBytes("UTF-8");
			requestClassNameBytes = requestClassName.getBytes("UTF-8");
			dataBytes = data.getBytes("UTF-8");
		} catch (UnsupportedEncodingException e) {
			log.error("将传来的数据打包成 byte 数组发生异常", e);
		}
		// 连接三个数组
		byte[] realDataBytes = ArrayUtil.concat(ArrayUtil.concat(requestClassNameBytes, colonBytes), dataBytes);
		// 得到长度及其 byte 数组
		int count = realDataBytes.length;
		byte[] countBytes = ByteHelper.intToBytes(count);
		// 将长度信息加在数据前面
		byte[] result = ArrayUtil.concat(countBytes, realDataBytes);
		return result;
	}
	
	/**
	 * 解析读取到的数据
	 * @param count
	 * @param request
	 */
	public void parseData (int count, Request request) {
		dataCount += count;
		// 数据足够解析
		while (dataCount > 4) {
			int length = ByteHelper.bytesToInt(data);
			// 要解析的数据查长度必须小于等于 dataCount - 4（减4是因为前4个字节存储的长度信息）
			if (length + 4 <= dataCount && length > 0) {
				// 解析 byte 数据
				String str = null;
				try {
					str = new String(data, 4, length, "UTF-8");
				} catch (UnsupportedEncodingException e) {
					log.error("解析读取到的数据发生异常", e);
				}
				// 从字符串中解析出 RequestClassName, ControllerName, MethodName 和 dataStr
				String requestClassName = str.substring(0, str.indexOf(":"));
				// 去除 str 第一个冒号及前面的字符串
				str = str.substring(str.indexOf(":") + 1);
				String controllerName = str.substring(0, str.indexOf(":"));
				str = str.substring(str.indexOf(":") + 1);
				String methodName = str.substring(0, str.indexOf(":"));
				str = str.substring(str.indexOf(":") + 1);
				String dataStr = str;
				// 数组的存储的数据的长度减少 length + 4
				dataCount -= length + 4;
				// 除去数组的前 length + 4 个数据
				System.arraycopy(data, length + 4, data, 0, dataCount);
				// 四个数据都已经得到，调用处理请求的方法
				request.handleRequest(requestClassName, controllerName, methodName, dataStr);
			} else {
				break;
			}
		}
	}
	
	/**
	 * 返回 data 数组中还剩余的空间
	 * @return
	 */
	public int remineSize () {
		return data.length - dataCount;
	}
	
	public byte[] getData() {
		return data;
	}

	public int getDataCount() {
		return dataCount;
	}

	public void setData(byte[] data) {
		this.data = data;
	}
}
